home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / t_os / book / src / keyio.c < prev    next >
C/C++ Source or Header  |  1993-07-08  |  9KB  |  328 lines

  1. /*
  2.  *  keyboard low I/O
  3. */
  4.  
  5. #include    <stdio.h>
  6. #include    <stdlib.h>
  7. #include    <string.h>
  8. #include    <string.h>
  9. #include    <ctype.h>
  10. #include    <egb.h>
  11. #include    <mos.h>
  12. #include    <fmc.h>
  13. #include    "book.h"
  14. #include    "oaklib.h"
  15. #include    "keyio.h"
  16. #include    "lib.h"
  17. #include    "menu_evt.h"
  18. #include    "init.h"
  19.  
  20.  
  21.  
  22.  
  23. /*
  24.  *  エンコード・モードのキー入力
  25. */
  26.  
  27. static  int     kb_char = 0xFFFF;
  28. static  u_int   kb_encode = 0;
  29.  
  30. #if 0           /*  Break/COPY の検出をするときは、"1" にする  */
  31.  
  32. static  u_char  matrix[16];
  33. static  u_int   now_break = OFF, now_copy = OFF;
  34. static  u_int   last_break = OFF, last_copy = OFF;
  35.  
  36. int     kbhit(void)
  37. {
  38.     last_break = now_break, last_copy = now_copy;
  39.     KYB_matrix((char *)matrix);
  40.     now_break = ((matrix[15]) & 0x10) != 0 ? ON:OFF;
  41.     now_copy  = ((matrix[15]) & 0x20) != 0 ? ON:OFF;
  42.  
  43.     if (last_break == ON && now_break == OFF)
  44.     {
  45.         kb_char = 0x8000, kb_encode = 0x7C00;
  46.         return 1;
  47.     }
  48.     if (last_copy == ON && now_copy == OFF)
  49.     {
  50.         kb_char = 0x8000, kb_encode = 0x7D00;
  51.         return 1;
  52.     }
  53.  
  54.     if (kb_char != 0xFFFF || (kb_char = KAN_read(1, &kb_encode)) != 0xFFFF)
  55.         return 1;
  56.     else
  57.         return 0;
  58. }
  59. #else
  60. int     kbhit(void)
  61. {
  62.     if (kb_char != 0xFFFF || (kb_char = KAN_read(1, &kb_encode)) != 0xFFFF)
  63.         return 1;
  64.     else
  65.         return 0;
  66. }
  67. #endif
  68.  
  69. static  u_char  _cnvtbl[] =
  70. {       /* このキーアドレスだったら、「0x8000 + キーアドレス」に変換する */
  71.     0x4D,   /* ↑ */            0x4F,   /* ← */
  72.     0x50,   /* ↓ */            0x51,   /* → */
  73.     0x01,   /* ESC */           0x10,   /* TAB */
  74.     0x57,   /* 無変換 */        0x58,   /* 変換 */
  75.     0x59,   /* かな漢字 */      0x5A,   /* カナ */
  76.     0x56,   /* ひらがな */
  77.     0x1D,   /* 改行 */          0x45,   /* 改行(テンキー) */
  78.     0x73,   /* 実行 */          0x72,   /* 取消 */
  79.     0x0F,   /* BS */            0x48,   /* 挿入 */
  80.     0x6B,   /* 漢字辞書 */      0x6C,   /* 単語抹消 */
  81.     0x6D,   /* 単語登録 */      0x4E,   /* HOME */
  82.     0x6E,   /* 前行 */          0x70,   /* 次行 */
  83.     0x71,   /* 半角/全角 */    0x4B,   /* 削除 */
  84.  
  85.     0x7C,   /* BREAK */         0x7D,   /* COPY */
  86.  
  87.     0x5D,   /* PF1 */           0x5E,   /* PF2 */
  88.     0x5F,   /* PF3 */           0x60,   /* PF4 */
  89.     0x61,   /* PF5 */           0x62,   /* PF6 */
  90.     0x63,   /* PF7 */           0x64,   /* PF8 */
  91.     0x65,   /* PF9 */           0x66,   /* PF10 */
  92.     0x69,   /* PF11 */          0x5B,   /* PF12 */
  93.     0x74,   /* PF13 */          0x75,   /* PF14 */
  94.     0x76,   /* PF15 */          0x77,   /* PF16 */
  95.     0x78,   /* PF17 */          0x79,   /* PF18 */
  96.     0x7A,   /* PF19 */          0x7B,   /* PF20 */
  97. };
  98. static  char    cnvtbl[256];    /* こっちが本当のテーブル */
  99.  
  100. void    kb_setup_cnvtbl(void)
  101. {
  102. int     i;
  103.  
  104.     memset(cnvtbl, '\0', 256);
  105.  
  106.     for (i = 0; i < sizeof(_cnvtbl)/sizeof(u_char); i++)
  107.         cnvtbl[_cnvtbl[i]] = '\1';
  108. }
  109.  
  110. /*
  111.  *  キーボードからの一文字入力 (入力待ちをおこなう)
  112.  *
  113.  *  入力
  114.  *      なし
  115.  *  出力
  116.  *      int ch      - 入力されたキー情報がパックされて返される
  117.  *                      PF, 機能キー → bit    8 セット
  118.  *                                      bit  0-7 キーアドレス
  119.  *                                      bit12-15 シフト状態
  120.  *                      通常キー     → bit    8 リセット
  121.  *                                      bit  0-7 キャラクタコード
  122.  *                    ただし、シフト状態として返されるのは、bit12,13,14,15
  123.  *                      (シフト、コントロール、左右親指シフト)のみ
  124. */
  125. int     getch(void)
  126. {
  127. int    ch;
  128.  
  129.     do {
  130.         while (kbhit() == 0)    /* 入力待ち */
  131.             ;
  132.         ch = kb_char;  kb_char = 0xFFFF;
  133.     } while (ch == 0);
  134.  
  135.     if (cnvtbl[kb_encode >> 8]) {
  136.         ch = (kb_encode >> 8) |             /* bit 0~7 はキーアドレス */
  137.              (1 << 8) |                     /* bit 8 をセット */
  138.              ((kb_encode & 0x04) << 10) |   /* bit12 はシフトキー */
  139.              ((kb_encode & 0x70) << 9);     /* bit13~15 はのこり */
  140.     }
  141.  
  142.     return ch;
  143. }
  144.  
  145. void    keyflush(void)
  146. {
  147.     KYB_clrbuf();
  148.  
  149.     while (kbhit())
  150.         getch();
  151. }
  152.  
  153.  
  154.  
  155.  
  156. /*
  157.  *  キーアサインの保存と復元
  158. */
  159.  
  160. typedef struct  {
  161.     short   sw, code, chrcnt;
  162.     char    buf[16];
  163. }   kb_tbl_t;
  164. typedef struct  {
  165.     kb_tbl_t    tbl[48];
  166.     int         num;        /*  いくつのキーアサインを保存したか  */
  167. }   asign_t;
  168.  
  169. static  asign_t asign[ASIGN_PUSH_MAX];
  170. static  int     asign_num = 0;
  171.  
  172.  
  173. void    kb_asign_push( void )
  174. {
  175.     asign_t     *ap ;
  176.     int         i ;
  177.  
  178.     if( asign_num >= ASIGN_PUSH_MAX )   /*  これ以上保存できない  */
  179.         return ;
  180.     ap = &asign[asign_num++] ;
  181.  
  182.     void    rdassign( asign_t *ap, int code, int num )
  183.     {
  184.         int     sw, chrcnt ;
  185.         char    buf[32] = "\x0F" ;
  186.  
  187.         KYB_rdasign( &sw, code, &chrcnt, buf ) ;
  188.  
  189.         ap->tbl[num].sw = sw ;
  190.         ap->tbl[num].code = code ;
  191.         ap->tbl[num].chrcnt = chrcnt ;
  192.         memcpy( ap->tbl[num].buf, buf+1, chrcnt ) ;
  193.         ap->tbl[num].buf[chrcnt] = '\0' ;
  194.     }
  195.  
  196.     ap->num = 0 ;
  197. #if 0
  198.     for( i = 0x8001 ; i <= 0x800B ; i++, ap->num++ )
  199.         rdassign( ap, i, ap->num ) ;
  200.     for( i = 0x8011 ; i <= 0x8018 ; i++, ap->num++ )
  201.         rdassign( ap, i, ap->num ) ;
  202.     for( i = 0x801c ; i <= 0x801f ; i++, ap->num++ )
  203.         rdassign( ap, i, ap->num ) ;
  204.     for( i = 0x8021 ; i <= 0x8028 ; i++, ap->num++ )
  205.         rdassign( ap, i, ap->num ) ;
  206. #endif
  207.     for( i = 0x8001 ; i <= 0x8028 ; i++, ap->num++ )
  208.         rdassign( ap, i, ap->num ) ;
  209.     rdassign( ap, 0x7F, ap->num++ ) ;
  210. }
  211. void    kb_asign_pop( void )
  212. {
  213.     asign_t     *ap ;
  214.     int         i ;
  215.  
  216.     if( asign_num < 1 )         /*  保存されていない  */
  217.         return ;
  218.     ap = &asign[--asign_num] ;
  219.  
  220.     for( i = 0 ; i < ap->num ; i++ )
  221.         KYB_asign( ap->tbl[i].sw,
  222.                    ap->tbl[i].code, ap->tbl[i].chrcnt, ap->tbl[i].buf ) ;
  223. }
  224.  
  225.  
  226.  
  227.  
  228. /*
  229.  *  マトリクスによるキー入力
  230. */
  231.  
  232. static  int     active_char = 0;    /* 現在押されているキーアドレス */
  233. static  u_int   start_time = 0;     /* ↑が押し始められた時間 */
  234. static  int     repeat_start = FALSE;   /* リピート開始フラグ */
  235.  
  236.  
  237. /* キーボード入力チェック */
  238.  
  239. static  int     _kb_check(void)
  240. {
  241. #define BITS                   (8)  /* バイト型のビット数 */
  242. #define pSHIFT         (0x53 / BITS)  /* シフトキーのバイト位置 */
  243. #define mSHIFT    (1<<(0x53 % BITS))  /* シフトキーのビット位置 */
  244. #define pCTRL         (0x52 / BITS)  /* コントロールキーのバイト位置 */
  245. #define mCTRL    (1<<(0x52 % BITS))  /* コントロールキーのビット位置 */
  246. #ifdef USE_OYAYUBI
  247. # define pLSHIFT         (0x67 / BITS)  /* 左親指シフトキーのバイト位置 */
  248. # define mLSHIFT    (1<<(0x67 % BITS))  /* 左親指シフトキーのビット位置 */
  249. # define pRSHIFT         (0x68 / BITS)  /* 右親指シフトキーのバイト位置 */
  250. # define mRSHIFT    (1<<(0x68 % BITS))  /* 右親指シフトキーのビット位置 */
  251. #endif
  252. static  u_long  matrix[4];
  253.         u_char  *p = (u_char *)matrix;
  254.         u_long  i, val;
  255.         u_long  shift = 0;
  256.  
  257.     KYB_matrix((char *)matrix);
  258.  
  259.     shift |= (p[pSHIFT ] & mSHIFT ) ? 0x100 : 0;     /* シフトキー */
  260.     p[pSHIFT] &= (0xFF ^ mSHIFT);
  261.     shift |= (p[pCTRL  ] & mCTRL  ) ? 0x200 : 0;     /* コントロールキー */
  262.     p[pCTRL] &= (0xFF ^ mCTRL);
  263. #ifdef USE_OYAYUBI
  264.     shift |= (p[pLSHIFT] & mLSHIFT) ? 0x400 : 0;     /* 左親指シフト */
  265.     p[pLSHIFT] &= (0xFF ^ mLSHIFT);
  266.     shift |= (p[pRSHIFT] & mRSHIFT) ? 0x800 : 0;     /* 左親指シフト */
  267.     p[pRSHIFT] &= (0xFF ^ mRSHIFT);
  268. #endif
  269.  
  270.     if (matrix[0] || matrix[1] || matrix[2] || matrix[3])
  271.     {
  272.         KYB_clrbuf();
  273.  
  274.         for (i = 0; i < 16; i++)
  275.         {
  276.             if ((val = p[i]) != 0)
  277.             {
  278.                 for (i *= 8; (val & 1) == 0; i++)
  279.                     val >>= 1;
  280.                 return shift | i;
  281.             }
  282.         }
  283.     }
  284.  
  285.     return shift;
  286. }
  287.  
  288. int     kb_check(void)
  289. {
  290. int     code;
  291.  
  292.     code = _kb_check();
  293.  
  294.     if (active_char != code)
  295.     {
  296.         active_char = code;         /* 現在押されているキーアドレス */
  297.         start_time = MOS_getTime(); /* ↑が押し始められた時間 */
  298.         repeat_start = FALSE;       /* リピート開始フラグ */
  299.     }
  300.     return code;
  301. }
  302.  
  303. /* キーから手を離すか、リピート時間が経過すると復帰する */
  304.  
  305. void    wait_repeat(void)
  306. {
  307. int     code = active_char;
  308. int     start = start_time;
  309. int     last = MOS_getTime();
  310.  
  311.     while (code == _kb_check())     /* キーが押されていたら */
  312.     {
  313.         if (repeat_start)           /* リピート中 */
  314.         {
  315.             if (MOS_getTime() - last > setup.repeat)
  316.                 break;
  317.         }
  318.         else                        /* リピート開始待ち */
  319.         {
  320.             if (MOS_getTime() - start > setup.repstart) {
  321.                 repeat_start = TRUE;
  322.                 break;
  323.             }
  324.         }
  325.     }
  326. }
  327.  
  328.